package com.gxnzd.communityelderly.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxnzd.communityelderly.commom.BaseContext;
import com.gxnzd.communityelderly.commom.JwtUtils;
import com.gxnzd.communityelderly.commom.OSS;
import com.gxnzd.communityelderly.commom.R;
import com.gxnzd.communityelderly.dao.EmployeeList;
import com.gxnzd.communityelderly.dao.ResHomeInfo;
import com.gxnzd.communityelderly.dao.ResUserPieInfo;
import com.gxnzd.communityelderly.dao.ResUserRatio;
import com.gxnzd.communityelderly.entity.*;
import com.gxnzd.communityelderly.mapper.*;
import com.gxnzd.communityelderly.service.CommunityService;
import com.gxnzd.communityelderly.service.EmployeeService;
import com.gxnzd.communityelderly.service.ForumService;
import com.gxnzd.communityelderly.service.SchedulingService;
import org.apache.commons.lang.StringUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ClassName: UserServiceImpl
 * Package: com.gxnzd.communityelderly.service.impl
 * Description:
 *
 * @Author 胡海峰
 * @Create 2024/10/1 21:44
 * @Version 1.0
 */
@Service
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {
    @Resource
    private EmployeeMapper employeeMapper;
    @Resource
    private DiagnosisMapper diagnosisMapper;

    
    @Resource
    private CommunityMapper communityMapper;
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private SchedulingMapper schedulingMapper;

    @Resource
    private ForumService forumService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private ReservationMapper reservationMapper;

    @Resource
    private OSS oss;

    /**
     * 登录 方法
     * @param employee
     * @return
     */
    public R login_user(Employee employee){
        String userName = employee.getUserName();
        String password = employee.getPassword();

        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUserName,userName);
        Employee emp = employeeMapper.selectOne(wrapper);
        //判断账号
        if(emp == null) return R.error("账号错误！");

        //判断密码
        password = DigestUtils.md5DigestAsHex(employee.getPassword().getBytes());
        if(!emp.getPassword().equals(password)){
            return R.error("请输入正确的密码");
        }

       //判断状态
        if (emp.getStatus() == 0){
            return R.error("用户状态不可用!");
        }
        //生成token
        Employee userInfo = new Employee();
        userInfo.setEmpId(emp.getEmpId());
        userInfo.setUserName(emp.getUserName());
        userInfo.setPassword(emp.getPassword());
        String token = jwtUtils.generateToken(userInfo);

        HashMap<String, Object> map = new HashMap<>();
        map.put("emp",emp);
        map.put("token",token);
//        request.getSession().setAttribute("empId", emp.getEmpId());
        return R.success(map);
    }

    @Override
    public R logoutToken(HttpServletRequest request) {
        //获取token
        String token = request.getHeader("Authorization");
        //作废token
        String s = jwtUtils.cancelToken(token);

        return R.success(s);
    }

    /**
     * 新增员工
     * @param employee
     * @return
     */
    public R insertEmployee(Employee employee) {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUserName,employee.getUserName());
        Employee one = employeeMapper.selectOne(wrapper);
        if(one != null){
            return R.error("当前员工已存在!");
        }
        //判断传过来的员工绑定了社区id
        if (employee.getCommunityId() == null){
            return R.error("请绑定社区");
        }
        if("".equals(employee.getAvatar())){
            employee.setAvatar("http://snlhp322m.hn-bkt.clouddn.com/1732690007828.jpg");
        }
        //对身份类型进行识别
        if (employee.getType() == null){
            return R.error("请选择添加人的身份！");
        }
        //如果身份是用户 则必须传入出生日期
        if(employee.getType() == 2 && employee.getBirthDate() == null){
            return R.error("请传入用户的出生日期");
        }
        if(employee.getType() == 2 && employee.getBirthDate() != null){
            Calendar calendar = Calendar.getInstance();
            int age = calendar.get(Calendar.YEAR) - employee.getBirthDate().getYear();
            employee.setAge(age);
        }


        if (!validatePhoneNumber(employee.getPhone())){
            return R.error("请输入正确的手机号");
        }
        //对状态进行默认值设置
        employee.setStatus(1);
        //对密码进行加密
        employee.setPassword(DigestUtils.md5DigestAsHex(employee.getPassword().getBytes()));
        //写入到数据库
        employeeMapper.insert(employee);
        //新增医生的话 默认给添加一份排班表
        if (employee.getType() == 3){
            String monday = new String("{\"morning\":0,\"afternoon\":0}");
            String tuesday = new String("{\"morning\":0,\"afternoon\":0}");
            String wednesday = new String("{\"morning\":0,\"afternoon\":0}");
            String thursday = new String("{\"morning\":0,\"afternoon\":0}");
            String friday = new String("{\"morning\":0,\"afternoon\":0}");
            String saturday = new String("{\"morning\":0,\"afternoon\":0}");
            String sunday = new String("{\"morning\":0,\"afternoon\":0}");
            Scheduling scheduling = new Scheduling();
            scheduling.setMonday(monday);
            scheduling.setTuesday(tuesday);
            scheduling.setWednesday(wednesday);
            scheduling.setThursday(thursday);
            scheduling.setFriday(friday);
            scheduling.setSaturday(saturday);
            scheduling.setSunday(sunday);
            scheduling.setCommunityId(employee.getCommunityId());
            Employee selectEmp = employeeMapper.selectOne(wrapper);
            scheduling.setDoctorId(selectEmp.getEmpId());
            schedulingMapper.insert(scheduling);
        }


        return R.success("添加成功!");
    }

    /**
     * 查询
     * @param page
     * @param pageSize
     * @param userName
     * @param name
     * @param type
     * @return
     */
    @Override
    public R<Page> getList(Integer page, Integer pageSize, String userName, String name, Integer type) {
        Page<EmployeeList> listPage = new Page<>();
        Page<Employee> pageInfo = new Page<>(page,pageSize);
        //获取当前线程的登录用户的id
        Long empId = BaseContext.getThreadLocal();
        //查询条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name), Employee::getName, name)
                .like(StringUtils.isNotEmpty(userName),Employee::getUserName,userName)
                .orderByDesc(Employee::getCreateTime);
        if(type != null){
            wrapper.eq(Employee::getType,type);
        }
        //不是超级管理员只能查看到当前登录用户的社区用户
        if(empId != 0){
            Employee employee = employeeMapper.selectById(empId);
            wrapper.eq(Employee::getCommunityId,employee.getCommunityId());
        }

        //分页器
        Page<Employee> employeePage = employeeMapper.selectPage(pageInfo, wrapper);

        List<EmployeeList> empNewList=new ArrayList<>();
        //循环用户分页器进行拿到每个用户的社区id
        for (Employee employee:employeePage.getRecords()) {
            Integer communityId = employee.getCommunityId();
            Community community = communityMapper.selectById(communityId);
            if (community == null){
                continue;
            }
            EmployeeList employeeList =new EmployeeList();
            //复制一个用户到新的用户列表 并把社区名称写进去
            BeanUtils.copyProperties(employee, employeeList);
            employeeList.setCommunityName(community.getCommunityName());
            empNewList.add(employeeList);
        }
        //对新的分页器进行填充
        listPage.setRecords(empNewList);
        listPage.setPages( employeePage.getPages());
        listPage.setCurrent( employeePage.getCurrent());
        listPage.setSize( employeePage.getSize());
        listPage.setTotal( employeePage.getTotal());

        return R.success(listPage);
    }

    /**
     * 修改用户
     * @param employee
     * @return
     */
    @Override
    public R updateEmployee(Employee employee) {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getEmpId,employee.getEmpId());

        Employee selectOne = employeeMapper.selectOne(wrapper);
        if(selectOne == null){
            return R.error("请传入正确的用户id");
        }
        if("".equals(employee.getAvatar())){
            employee.setAvatar("/src/assets/userImg/1729217391500.jpg");
        }
        //判断传过来的员工绑定了社区id
        if (employee.getCommunityId() == null){
            return R.error("请绑定社区");
        }
        //对身份类型进行识别
        if (employee.getType() == null){
            return R.error("请选择添加人的身份！");
        }

        //如果身份是用户 则必须传入出生日期
        if(employee.getType() == 2 && employee.getBirthDate() == null){
            return R.error("请传入用户的出生日期");
        }
        if(employee.getType() == 2 && employee.getBirthDate() != null){
            Calendar calendar = Calendar.getInstance();
            int age = calendar.get(Calendar.YEAR) - employee.getBirthDate().getYear();
            employee.setAge(age);
        }

        if (!validatePhoneNumber(employee.getPhone())){
            return R.error("请输入正确的手机号");
        }

        //判断此修改的用户是否是医生 并且 改了社区 再对排班表的社区进行修改
        if (employee.getType() == 3 &&  selectOne.getCommunityId() != employee.getCommunityId()){
            LambdaQueryWrapper<Scheduling> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Scheduling::getDoctorId,selectOne.getEmpId());
            Scheduling scheduling = schedulingMapper.selectOne(queryWrapper);
            scheduling.setCommunityId(employee.getCommunityId());
            schedulingMapper.updateById(scheduling);
        }
        employeeMapper.updateById(employee);

        return R.success("修改成功");
    }


    /**
     * 删除员工
     * @param empId
     * @return
     */
    public R deleteEmployee(Long empId){
        Long ThreadId = BaseContext.getThreadLocal();
        if(ThreadId == empId){
            return R.error("不能将自己身份删除！");
        }
        Employee employee = employeeMapper.selectById(empId);
        //同时删除预约服务中改用户的信息
        LambdaQueryWrapper<Reservation> wrapper = new LambdaQueryWrapper<>();
        if(employee.getType() == 2){
            wrapper.eq(Reservation::getUserId,empId);
            reservationMapper.delete(wrapper);
            LambdaQueryWrapper<Diagnosis> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Diagnosis::getUserId,empId);
        }else if(employee.getType() ==3){
            wrapper.eq(Reservation::getDoctorId,empId);
            reservationMapper.delete(wrapper);
            LambdaQueryWrapper<Diagnosis> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Diagnosis::getUserId,empId);
            diagnosisMapper.delete(queryWrapper);
            LambdaQueryWrapper<Scheduling> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Scheduling::getDoctorId,empId);
            schedulingMapper.delete(lambdaQueryWrapper);
        }
        //删除oss云端用户头像
        String[] urlList=employee.getAvatar().split("/");
        oss.deletePhoto(urlList[urlList.length-1]);
        employeeMapper.deleteById(empId);
        return R.success("删除成功");
    }

    /**
     * 模糊查询
     * @param name
     * @param type
     * @return
     */
    @Override
    public R<List<Employee>> seleteList(String name, Integer type) {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
        if(type != null){
            wrapper.eq(Employee::getType,type);
        }
        List<Employee> employeeList = employeeMapper.selectList(wrapper);
        return R.success(employeeList);
    }

    /**
     * 校验手机号码是否合法
     *
     * @param phoneNumber 要校验的手机号码
     * @return 如果手机号码合法则返回true，否则返回false
     */
    public static boolean validatePhoneNumber(String phoneNumber) {
        // 创建手机号码正则表达式的模式
        Pattern pattern = Pattern.compile("^1[34578]\\d{9}$");
        // 使用模式匹配手机号码
        Matcher matcher = pattern.matcher(phoneNumber);
        // 返回匹配结果
        return matcher.matches();
    }

    /**
     * 修改密码
     * @param employee
     * @return
     */
    @Override
    public R modifyPassword(Employee employee) {

        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUserName,employee.getUserName())
                .eq(Employee::getPhone,employee.getPhone());
        Employee one = employeeMapper.selectOne(wrapper);
        if(one == null){
            return R.error("用户账号或者手机号不正确！");
        }
        one.setPassword(DigestUtils.md5DigestAsHex(employee.getPassword().getBytes()));
        employeeMapper.updateById(one);
        return R.success("修改成功");
    }

    /**
     * 手机号验证
     * @param employee
     * @return
     */
    @Override
    public R phoneLogin(Employee employee) {
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getPhone,employee.getPhone());
        Employee one = employeeMapper.selectOne(wrapper);
        if(one == null){
            return R.error("没有此手机号的用户");
        }
        if(one.getType() != 2){
            return R.error("只有用户才能登录");
        }
        Employee userInfo = new Employee();
        userInfo.setEmpId(one.getEmpId());
        userInfo.setUserName(one.getUserName());
        userInfo.setPassword(one.getPassword());
        String token = jwtUtils.generateToken(userInfo);
        HashMap<String, Object> map = new HashMap<>();
        map.put("emp",one);
        map.put("token",token);
        return R.success(map);

    }

    /**
     * 获取各个角色的占比
     * @return
     */
    @Override
    public R getRatio() {
        //总人数
        LambdaQueryWrapper<Employee> employeeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        employeeLambdaQueryWrapper.gt(Employee::getType,0);
        List<Employee> allList = employeeMapper.selectList(employeeLambdaQueryWrapper);
        ResUserPieInfo pieInfo = new ResUserPieInfo();
        pieInfo.setTotal(allList.size());
        //管理员的
        ResUserRatio adminRatioInfo = countEmpTypeSum(1, allList.size(), "管理员");
        pieInfo.setAdmin(adminRatioInfo);
        //用户的
        ResUserRatio userRatioInfo = countEmpTypeSum(2, allList.size(), "普通用户");
        pieInfo.setUser(userRatioInfo);
        //医生的
        ResUserRatio doctorRatioInfo = countEmpTypeSum(3, allList.size(), "社区医生");
        pieInfo.setDoctor(doctorRatioInfo);
        return R.success(pieInfo);
    }

    /**
     * 获取用户类型数量
     * @param type
     * @param totalNum
     * @param typeName
     * @return
     */
    public ResUserRatio countEmpTypeSum(Integer type,Integer totalNum,String typeName){
        ResUserRatio inInfo = new ResUserRatio();
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getType,type);
        List<Employee> List = employeeMapper.selectList(wrapper);
        inInfo.setTypeName(typeName);
        inInfo.setRatio (List.size());
        return inInfo;
    }

    /**
     * 获取首页的详情信息
     * @return
     */
    @Override
    public R getHomeInfo() {

        ResHomeInfo homeInfo = new ResHomeInfo();
        //获取社区的数量
        LambdaQueryWrapper<Community> wrapper = new LambdaQueryWrapper<>();
        Long countCommunity = communityMapper.selectCount(wrapper);
        homeInfo.setCountCommunity(countCommunity);
        //获取员工数量
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        Long countEmp = employeeMapper.selectCount(queryWrapper);
        homeInfo.setCountEmp(countEmp);
        //获取帖子数量
        long countForum = forumService.count();
        homeInfo.setCountForum(countForum);

        return R.success(homeInfo);
    }
}
